
import EventPackage.Event;
import InstrumentationPackage.Indicator;

/**
 * Abstract controller used as basis for system controllers.
 *
 * @author Kyle Benedict
 */
public abstract class Controller extends EventProcessor {

    protected boolean enabled;        // State of the controller, whether it is enabled (true) or disabled (false)
    protected Indicator indicator;
    protected HeartBeat heartBeat;

    /**
     * Constructor for the controller.  Takes the event manager IP address
     * as a parameter and registers the controller with the event manager
     * hosted at that IP address.  Also takes an input parameter that defines
     * the delay in ms between event handling.
     * @param eventManagerIPAddress
     * @param delayBetweenEventsMillis
     */
    public Controller(String eventManagerIPAddress, long delayBetweenEventsMillis) {
        super(eventManagerIPAddress, delayBetweenEventsMillis);
    }

    /**
     * Constructor for the controller.  Assumes the event manager runs
     * at the localhost and takes an input parameter that defines the delay
     * in ms between event handling.
     * @param delayBetweenEventsMillis
     */
    public Controller(long delayBetweenEventsMillis) {
        this(null, delayBetweenEventsMillis);
    }

    protected abstract int getHeartbeatEventId();

    protected void writeConsoleMessage(String message) {
        if (registered) {
            Event event = new Event(EventType.CONSOLE_MESSAGE.getEventId(), message);
            try {
                getEventManager().SendEvent(event);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    protected void setIndicator(Indicator indicator) {
        this.indicator = indicator;
    }

    protected void setIndicatorMessageAndColor(String message, int color) {
        if (indicator != null) {
            indicator.SetLampColorAndMessage(message, color);
        }
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
        String name = this.getClass().getSimpleName();
        writeConsoleMessage((enabled ? "Enabled controller: " : "Disabled controller: ") + name);
    }

    public boolean isEnabled() {
        return enabled;
    }

    public static final Indicator createIndicator(String indicatorText, float posX, float posY, int initialColor) {
        return new Indicator(indicatorText, posX, posY, initialColor);
    }

    @Override
    protected void onRegistered() {
        String name = this.getClass().getSimpleName();
        writeConsoleMessage("Registered controller: " + name);
        if (eventManagerIPAddress == null) {
            heartBeat = new HeartBeat(getHeartbeatEventId());
        } else {
            heartBeat = new HeartBeat(getHeartbeatEventId(), eventManagerIPAddress);
        }
        heartBeat.start();
    }

   @Override
    protected void onUnregistered() {
        String name = this.getClass().getSimpleName();
        writeConsoleMessage("Unregistered controller: " + name);
        heartBeat.Close();
    }

}
